package ar.edu.itba.it.pdc.protocol.email;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;

import ar.edu.itba.it.pdc.app.Madonna3;
import ar.edu.itba.it.pdc.protocol.exception.InvalidPOP3FormatException;
import ar.edu.itba.it.pdc.utils.TempFilesSetup;

public class Part {

	private static final String CRLF = TempFilesSetup.CRLF;
	private static final File DIR = TempFilesSetup.DIR;
	private static final String PREFIX = TempFilesSetup.PREFIX_PART;
	private static final String SUFFIX = TempFilesSetup.SUFFIX;
	
	private File part;
	private List<Header> headers;
	private List<Part> parts;
	
	public Part(Reader reader, String boundary){
		this.parts = null;
		this.headers = null;
		try {
			this.part = File.createTempFile(PREFIX, SUFFIX, DIR);
			build(new BufferedReader(reader), boundary);
			if (isMultipart()){
				this.parts = new ArrayList<Part>();
				partsGenerator();
			}
		} catch (IOException e) {
			throw new InvalidPOP3FormatException("Problems creating part file: " + e.getMessage());
		}
		
	}
	
	private void partsGenerator(){
		try {
			BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(this.part)));
			
			String line = null;
			String boundary = getBoundary();
			StringBuffer buffer = new StringBuffer();
			
			while((line = reader.readLine()) != null && !line.equals("--" + boundary + "--")){
				if (line.equals("--" + boundary)){
					if (buffer.length() != 0){
						this.parts.add(new Part(new StringReader(buffer.toString()), boundary));
						buffer.delete(0, buffer.length());
					}
				} else
					buffer.append(line + CRLF);
			}
			this.parts.add(new Part(new StringReader(buffer.toString()), boundary));
			buffer.delete(0, buffer.length());
			
		} catch(IOException e) {
			Madonna3.log.error("Problems parsing multipart part: " + e.getMessage());		
		}
	}
	
	private void build(BufferedReader reader, String boundary) throws IOException {
		try {
			FileWriter writer = new FileWriter(this.part);		
			String line = null;
			while((line = reader.readLine()) != null && !line.contains(boundary)){
				if (line.startsWith("Content-")){
					if (this.headers == null)
						this.headers = new ArrayList<Header>();
					String[] parts = line.split(":", 2);
					this.headers.add(new Header(parts[0], parts[1]));
				} else {
					writer.write(line + CRLF);
					writer.flush();
				}
			}			
			writer.flush();
		} catch (IOException e) {
			throw new InvalidPOP3FormatException("Problems parsing multipart message: " + e.getMessage());
		}
	}
	
	public Header getContentType(){
		if (this.headers == null)
			return null;
		for (Header header : this.headers)
			if (header.getName().contains("Content-Type"))
				return header;
		return null;
	}
	
	public String getBoundary(){
		Header header = getContentType();
		if (!isMultipart())
			return null;
		String[] boundary = header.getValue().split("boundary=", 2);
		return boundary[1].substring(1, boundary[1].length()-1);
	}
	
	public boolean isMultipart(){
		Header header = getContentType();
		return header != null && header.getValue().contains("multipart");
	}
}
